/**
 * Copyright (C) 2018-2020
 * All rights reserved, Designed By www.yixiang.co
 * 注意：
 * 本软件为www.yixiang.co开发研制，未经购买不得使用
 * 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
 * 一经发现盗用、分享等行为，将追究法律责任，后果自负
 */
package co.yixiang.modules.activity.rest;

import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import co.yixiang.api.ApiResult;
import co.yixiang.api.YshopException;
import co.yixiang.constant.SystemConfigConstants;
import co.yixiang.enums.AppFromEnum;
import co.yixiang.logging.aop.log.AppLog;
import co.yixiang.common.bean.LocalUser;
import co.yixiang.common.interceptor.AuthCheck;
import co.yixiang.constant.ShopConstants;
import co.yixiang.modules.activity.domain.YxStoreSeckill;
import co.yixiang.modules.activity.param.SeckillShareParam;
import co.yixiang.modules.activity.service.YxStoreSeckillService;
import co.yixiang.modules.activity.service.dto.SeckillTimeDto;
import co.yixiang.modules.activity.vo.SeckillConfigVo;
import co.yixiang.modules.activity.vo.StoreSeckillVo;
import co.yixiang.modules.activity.vo.YxStoreSeckillQueryVo;
import co.yixiang.modules.mp.config.WxMaConfiguration;
import co.yixiang.modules.order.service.YxStoreOrderCartInfoService;
import co.yixiang.modules.product.domain.YxStoreProduct;
import co.yixiang.modules.product.service.YxStoreProductRelationService;
import co.yixiang.modules.product.service.YxStoreProductService;
import co.yixiang.modules.services.CreatShareProductService;
import co.yixiang.modules.shop.domain.YxSystemAttachment;
import co.yixiang.modules.shop.domain.YxSystemGroupData;
import co.yixiang.modules.shop.service.YxSystemAttachmentService;
import co.yixiang.modules.shop.service.YxSystemConfigService;
import co.yixiang.modules.shop.service.YxSystemGroupDataService;
import co.yixiang.modules.shop.service.dto.YxSystemGroupDataQueryCriteria;
import co.yixiang.modules.user.domain.YxUser;
import co.yixiang.modules.user.service.YxUserService;
import co.yixiang.utils.FileUtil;
import co.yixiang.utils.OrderUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.awt.*;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * <p>
 * 商品秒杀产品前端控制器
 * </p>
 *
 * @author hupeng
 * @since 2019-12-14
 */
@Slf4j
@RestController
@RequestMapping
@Api(value = "商品秒杀", tags = "营销:商品秒杀", description = "商品秒杀")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class StoreSeckillController {

    private final YxStoreSeckillService yxStoreSeckillService;
    private final YxSystemGroupDataService yxSystemGroupDataService;
    private final YxStoreProductRelationService relationService;
    private final YxStoreOrderCartInfoService orderCartInfoService;
    private final YxUserService yxUserService;
    private final YxSystemConfigService systemConfigService;
    private final YxStoreProductService storeProductService;
    private final YxSystemAttachmentService systemAttachmentService;
    private final CreatShareProductService creatShareProductService;

    @Value("${file.path}")
    private String path;

    /**
     * 秒杀产品列表
     */
    @GetMapping("/seckill/list/{time}")
    @ApiOperation(value = "秒杀产品列表", notes = "秒杀产品列表")
    public ApiResult<List<YxStoreSeckillQueryVo>> getYxStoreSeckillPageList(@PathVariable String time,
                                                       @RequestParam(value = "page",defaultValue = "1") int page,
                                                       @RequestParam(value = "limit",defaultValue = "10") int limit){
        if (StrUtil.isBlank(time) || !NumberUtil.isNumber(time)){
            throw new YshopException("参数错误");
        }
        return ApiResult.ok(yxStoreSeckillService.getList(page, limit, Integer.valueOf(time)));
    }


    /**
     * 根据id获取商品秒杀产品详情
     */
    @AppLog(value = "根据id获取商品秒杀产品详情", type = 1)
    @AuthCheck
    @GetMapping("/seckill/detail/{id}")
    @ApiOperation(value = "秒杀产品详情", notes = "秒杀产品详情")
    public ApiResult<Map<String,Object>> getYxStoreSeckill(@PathVariable Long id){
        Long uid = LocalUser.getUser().getUid();
        YxUser user =yxUserService.getById(uid);
        Map<String,Object> map = new LinkedHashMap<>();
        StoreSeckillVo storeSeckillVo = yxStoreSeckillService.getDetail(id, uid);
        storeSeckillVo.setUserCollect(relationService
                .isProductRelation(storeSeckillVo.getStoreInfo().getProductId(),uid));
        //查询用户是否购买并且已支付过秒杀产品
        String countShare =orderCartInfoService.getOrderCountBySeckill4apay(uid,id,storeSeckillVo.getStoreInfo().getProductId());
        String whether_share ="Y";
        if(user.getLevel() ==0){
            if("0".equals(countShare)){
                whether_share ="N";
            }
        }
        map.put("whether_share",whether_share);
        map.put("storeSeckillVo",storeSeckillVo);
        return ApiResult.ok(map);
    }


    /**
     * 秒杀产品时间区间
     */
    @GetMapping("/seckill/index")
    @ApiOperation(value = "秒杀产品时间区间", notes = "秒杀产品时间区间")
    public ApiResult<SeckillConfigVo> getYxStoreSeckillIndex() {
        //获取秒杀配置
        AtomicInteger seckillTimeIndex = new AtomicInteger();
        SeckillConfigVo seckillConfigVo = new SeckillConfigVo();

        YxSystemGroupDataQueryCriteria queryCriteria = new YxSystemGroupDataQueryCriteria();
        queryCriteria.setGroupName(ShopConstants.YSHOP_SECKILL_TIME);
        List<YxSystemGroupData> yxSystemGroupDataList = yxSystemGroupDataService.queryAll(queryCriteria);
        String isSeckill =systemConfigService.getData(ShopConstants.YSHOP_HOME_IS_SECKILL);
        List<SeckillTimeDto> list = new ArrayList<>();
        int today = OrderUtil.dateToTimestampT(DateUtil.beginOfDay(new Date()));
        if("0".equals(isSeckill)){
            yxSystemGroupDataList.forEach(i -> {
                String jsonStr = i.getValue();
                JSONObject jsonObject = JSON.parseObject(jsonStr);
                int time = Integer.valueOf(jsonObject.get("time").toString());//时间 5
                int continued = Integer.valueOf(jsonObject.get("continued").toString());//活动持续事件  3
                SimpleDateFormat sdf = new SimpleDateFormat("HH");
                String nowTime = sdf.format(new Date());
                String index = nowTime.substring(0, 1);
                int currentHour = "0".equals(index) ? Integer.valueOf(nowTime.substring(1, 2)) : Integer.valueOf(nowTime);
                SeckillTimeDto seckillTimeDto = new SeckillTimeDto();
                seckillTimeDto.setId(i.getId());
                //活动结束时间
                int activityEndHour = time + continued;
                if (activityEndHour > 24) {
                    seckillTimeDto.setState("即将开始");
                    seckillTimeDto.setTime(jsonObject.get("time").toString().length() > 1 ? jsonObject.get("time").toString() + ":00" : "0" + jsonObject.get("time").toString() + ":00");
                    seckillTimeDto.setStatus(2);
                    seckillTimeDto.setStop(today + activityEndHour * 3600);
                } else {
                    if (currentHour >= time && currentHour < activityEndHour) {
                        seckillTimeDto.setState("抢购中");
                        seckillTimeDto.setTime(jsonObject.get("time").toString().length() > 1 ? jsonObject.get("time").toString() + ":00" : "0" + jsonObject.get("time").toString() + ":00");
                        seckillTimeDto.setStatus(1);
                        seckillTimeDto.setStop(today + activityEndHour * 3600);
                        seckillTimeIndex.set(yxSystemGroupDataList.indexOf(i));
                    } else if (currentHour < time) {
                        seckillTimeDto.setState("即将开始");
                        seckillTimeDto.setTime(jsonObject.get("time").toString().length() > 1 ? jsonObject.get("time").toString() + ":00" : "0" + jsonObject.get("time").toString() + ":00");
                        seckillTimeDto.setStatus(2);
                        seckillTimeDto.setStop(OrderUtil.dateToTimestamp(new Date()) + activityEndHour * 3600);
                    } else if (currentHour >= activityEndHour) {
                        seckillTimeDto.setState("已结束");
                        seckillTimeDto.setTime(jsonObject.get("time").toString().length() > 1 ? jsonObject.get("time").toString() + ":00" : "0" + jsonObject.get("time").toString() + ":00");
                        seckillTimeDto.setStatus(0);
                        seckillTimeDto.setStop(today + activityEndHour * 3600);
                    }
                }
                list.add(seckillTimeDto);
            });
        }
        seckillConfigVo.setSeckillTimeIndex(seckillTimeIndex.get());
        seckillConfigVo.setSeckillTime(list);
        return ApiResult.ok(seckillConfigVo);
    }

    /**
     * 秒杀海报
     */
    @AppLog(value = "生成秒杀海报", type = 1)
    @AuthCheck
    @PostMapping("/seckill/poster")
    @ApiOperation(value = "秒杀海报",notes = "秒杀海报")
    public ApiResult<Object> poster(@Validated @RequestBody SeckillShareParam param) throws IOException, FontFormatException {
        String siteUrl = systemConfigService.getData(SystemConfigConstants.SITE_URL);
        if(StrUtil.isEmpty(siteUrl)){
            throw new YshopException("未配置h5地址");
        }
        String apiUrl = systemConfigService.getData(SystemConfigConstants.API_URL);
        if(StrUtil.isEmpty(apiUrl)){
            throw new YshopException("未配置api地址");
        }
        YxUser userInfo = LocalUser.getUser();
        Long seckillId =Long.valueOf(param.getId());
        YxStoreSeckill storeSeckill = yxStoreSeckillService.getById(seckillId);
        if(ObjectUtil.isNull(storeSeckill)) {
            throw new YshopException("秒杀产品不存在");
        }
        String from =param.getFrom();
        YxStoreProduct productDTO = storeProductService.getById(storeSeckill.getProductId());
        String name = seckillId+"_"+userInfo.getUid() + "_"+from+"_seckill_share_wap.jpg";
        YxSystemAttachment attachment = systemAttachmentService.getInfo(name);
        String fileDir = path+"qrcode"+ File.separator;
        String qrcodeUrl = "";
        String str ="id="+seckillId+"-spread="+userInfo.getUid()+"-pageType=good";
        String url ="pages/activity/SeckillDetails/index";
        String spreadUrl = "";
        if(ObjectUtil.isNull(attachment)){
            //生成二维码
            File file = FileUtil.mkdir(new File(fileDir));
            if(AppFromEnum.ROUNTINE.getValue().equals(from)){
                /*siteUrl = siteUrl+"/pink/";
                QrCodeUtil.generate(siteUrl+"?pinkId="+pinkId+"&spread="+uid+"&pageType=group&codeType="+AppFromEnum.ROUNTINE.getValue(), 180, 180,
                        FileUtil.file(fileDir+name));*/
                getminiqrQr(str,fileDir,name,url);
            }
            else if(AppFromEnum.APP.getValue().equals(from)){
                siteUrl = siteUrl+"/pink/";
                QrCodeUtil.generate(siteUrl+"?id="+seckillId+"&spread="+userInfo.getUid()+"&pageType=group&codeType="+AppFromEnum.ROUNTINE.getValue(), 180, 180,
                        FileUtil.file(fileDir+name));
            }
            else if(AppFromEnum.H5.getValue().equals(from)){
                QrCodeUtil.generate(siteUrl+"/activity/group_rule/"+seckillId+"?spread="+userInfo.getUid(), 180, 180,
                        FileUtil.file(fileDir+name));
            }else {
                String uniUrl = systemConfigService.getData(SystemConfigConstants.UNI_SITE_URL);
                siteUrl =  StrUtil.isNotBlank(uniUrl) ? uniUrl :  ShopConstants.DEFAULT_UNI_H5_URL;
                QrCodeUtil.generate(siteUrl+"/"+url+"?id="+seckillId+"&spread="+userInfo.getUid(), 180, 180,
                        FileUtil.file(fileDir+name));
            }


            systemAttachmentService.newAttachment4SpreadAdd(name,String.valueOf(FileUtil.size(file)),
                    fileDir+name,"qrcode/"+name,userInfo.getUid(),"","4",seckillId);

            qrcodeUrl = apiUrl + "/api/file/qrcode/"+name;
        }else{
            qrcodeUrl = apiUrl + "/api/file/" + attachment.getSattDir();
        }
        String spreadPicName = seckillId+"_"+userInfo.getUid() + "_"+from+"_seckill_user_spread.jpg";
        String spreadPicPath = fileDir+spreadPicName;

        YxSystemAttachment attachmentT = systemAttachmentService.getInfo(spreadPicName);
        String rr = creatShareProductService.getSeckillRebateUrl(productDTO,qrcodeUrl,
                spreadPicName,spreadPicPath,apiUrl,userInfo,seckillId,storeSeckill.getImage());
        return ApiResult.ok(rr);
    }

    public void getminiqrQr(String sceneStr,String path,String name,String url) {
        OutputStream outputStream = null;
        InputStream inputStream = null;
        try {
            WxMaService wxMaService = WxMaConfiguration.getWxMaService();
            WxMaQrcodeService wxMaQrcodeService = wxMaService.getQrcodeService();
            File file = new File(path+name);
            if (!file.exists()){
                file.createNewFile();
            }
            outputStream = new FileOutputStream(file);
            WxMaCodeLineColor line_color = new WxMaCodeLineColor("0","0","0");
            byte[] qrCodeBytes = wxMaQrcodeService.createWxaCodeUnlimitBytes(sceneStr, url, 130, false, line_color, true);
            inputStream = new ByteArrayInputStream(qrCodeBytes);
            int len = 0;
            while ((len = inputStream.read(qrCodeBytes, 0, 1024)) != -1) {
                outputStream.write(qrCodeBytes, 0, len);
            }
            outputStream.flush();
        } catch (Exception ex) {
            log.info("生成小程序码失败，message:{}", ex.getMessage());
        } finally {
            try {
                outputStream.close();
            } catch (Exception ex) {
                log.error("关闭IO流失败,msg:{}", ex.getMessage());
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

